package com.vhall.component.service.redpacket.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.vhall.component.dao.redpacket.RedPacketMapper;
import com.vhall.component.entity.rebroadcast.RedPacketEntity;
import com.vhall.component.entity.redpacket.vo.StatVo;
import com.vhall.component.framework.common.utils.CollectionUtils;
import com.vhall.component.service.redpacket.common.RedpacketConstants;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;
import java.math.RoundingMode;
import java.util.List;

/**
 * @author xuyongzheng
 * @since 2021/3/21 18:55
 **/
@Service
public class RedPacketStatServiceImpl {

    @Autowired
    private RedPacketMapper redPacketMapper;
    @Autowired
    private RedisTemplate<String, String> redisTemplate;

    /**
     * 按照 source id 维度统计
     *
     * @param appId
     * @param sourceId
     * @param payStatus
     * @return
     */
    public StatVo statBySourceId(String appId, String sourceId, Integer payStatus) {
        StatVo result = new StatVo();
        //joinedUserCount入参
        String jskey = RedpacketConstants.COUNT_RED_PACKET_JOIN_BY_SOURCE_ID + appId + "_" + sourceId;
        int joinedUserCount = Math.toIntExact(redisTemplate.opsForSet().size(jskey));
        result.setJoinedUserCount(joinedUserCount);

        //getUserCount入参
        String uskey = RedpacketConstants.COUNT_RED_PACKET_USER_BY_SOURCE_ID + appId + "_" + sourceId;
        int getUserCount = Math.toIntExact(redisTemplate.opsForSet().size(uskey));
        result.setGetUserCount(getUserCount);

        //sourceId下所有红包总金额
        String amtSource = RedpacketConstants.COUNT_RED_PACKET_AMOUNT_BY_SOURCE_ID + appId;

        result.setGetAmount(BigDecimal.ZERO);

        String getAmount = (String) redisTemplate.opsForHash().get(amtSource, sourceId);
        if (StringUtils.isNotBlank(getAmount)) {
            BigDecimal amt = new BigDecimal(getAmount).setScale(2, RoundingMode.HALF_UP);
            result.setGetAmount(amt);
        }

        //推送次数
        QueryWrapper<RedPacketEntity> where = new QueryWrapper<>();
        where.eq("app_id", appId);
        where.eq("room_id", sourceId);
        where.eq("gift_type", 1);
        int count = redPacketMapper.selectCount(where);
        result.setPushCount(count);

        //清空wrapper
        where.clear();

        //pushAmount入参
        where.eq("app_id", appId);
        where.eq("room_id", sourceId);
        where.eq("pay_status", payStatus);
        result.setPushAmount(BigDecimal.ZERO);

        List<RedPacketEntity> packets = redPacketMapper.selectList(where);
        if (CollectionUtils.isNotEmpty(packets)) {
            BigDecimal pamt = packets.stream().map(RedPacketEntity::getAmount).reduce(BigDecimal.ZERO, BigDecimal::add);
            result.setPushAmount(pamt);
        }
        return result;
    }

    public StatVo statByRedPacketId(String appId, Long redPacketId, RedPacketEntity packet) {
        StatVo result = new StatVo();
        String joinKey = RedpacketConstants.COUNT_RED_PACKET_JOIN_BY_RED_PACKET_ID + redPacketId.toString();
        int joinedUserCount = Math.toIntExact(redisTemplate.opsForSet().size(joinKey));

        String getKey = RedpacketConstants.COUNT_RED_PACKET_USER_BY_RED_PACKET_ID + redPacketId.toString();
        int getUserCount = Math.toIntExact(redisTemplate.opsForSet().size(getKey));

        String amountK = RedpacketConstants.COUNT_RED_PACKET_AMOUNT_BY_RED_PACKET_ID + appId;
        String amountV = (String) redisTemplate.opsForHash().get(amountK, redPacketId.toString());
        BigDecimal getAmount = BigDecimal.ZERO;

        if (StringUtils.isNotBlank(amountV)) {
            getAmount = new BigDecimal(amountV).setScale(2, RoundingMode.HALF_UP);
        }

        result.setJoinedUserCount(joinedUserCount > packet.getJoinedUserCount() ? joinedUserCount : packet.getGetUserCount());
        result.setGetUserCount(getUserCount > packet.getGetUserCount() ? getUserCount : packet.getGetUserCount());
        result.setGetAmount(getAmount.compareTo(packet.getGetAmount()) > 0 ? getAmount : packet.getGetAmount());
        result.setPushAmount(packet.getAmount());
        result.setPushCount(0);
        return result;
    }
}
